#include <iostream>

// 深拷贝和浅拷贝
// 浅拷贝：简单的赋值操作
// 深拷贝：在堆区重新申请空间，进行拷贝操作

class Person
{
public:
    Person()
    {
        std::cout << "Person()" << std::endl;
    }
    Person(int age, int height)
    {
        m_Age = age;
        m_Height = new int(height);  // 在堆区创建空间
        std::cout << "Person(int age)" << std::endl;
    }
    ~Person()
    {
        std::cout << "~Person()" << std::endl;
        // 析构代码，将堆区开辟数据做释放操作
        if (m_Height != NULL)
        {
            delete m_Height;
            m_Height = NULL;    // 避免野指针
        }
        // 注意：如果是浅拷贝的话，这里会出现问题，两个对象会指向同一块堆区数据
        // 解决方法：深拷贝，在堆区重新申请空间，进行拷贝操作
        // 深拷贝的实现：在拷贝构造函数中，重新申请空间，将参数对象中的数据拷贝过来
    }
    // 拷贝构造函数
    Person(const Person &p)
    {
        m_Age = p.m_Age;
        // 深拷贝
        m_Height = new int(*p.m_Height);
        std::cout << "Person(const Person &p)" << std::endl;
    }
    int m_Age;
    int *m_Height;  
};

void test01()
{
    Person p1(18, 180);
    std::cout << "p1.m_Age = " << p1.m_Age << std::endl;
    std::cout << "p1.m_Height = " << *p1.m_Height << std::endl;
    Person p2(p1);
    // 未定义拷贝构造函数，编译器默认提供浅拷贝
    std::cout << "p2.m_Age = " << p2.m_Age << std::endl;
    std::cout << "p2.m_Height = " << *p2.m_Height << std::endl;
}

int main()
{
    test01();
    return 0;
}